/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package rentcalculator.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import rentcalculator.exception.InvalidDiscountsException;

/**
 *
 * @author K.E.Y
 */

@Entity
public class Facility {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private long id;
    private String name;
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="property_id")
    private Property property;
    
    @OneToMany(fetch = FetchType.EAGER)
    private List<Discount> billDiscounts;

    //if this facility require a bill
    private boolean billable;
    
    //if user is absent then he doesn't need to pay the bill generated during his absence
    @Column(name = "absent_free")
    private boolean absentfree;
    
    @Column(name="discount_enabled")
    private boolean discountEnabled;

    public List<Discount> getBillDiscounts() {
        checkDiscounts(this.billDiscounts);
        Comparator<Discount> priorityComparator;
        priorityComparator = new Comparator<Discount>(){
            @Override
            public int compare(Discount c1, Discount c2){
                return c1.getPriority() - c2.getPriority();
            }
        };
        Collections.sort(billDiscounts, priorityComparator);
        
        return billDiscounts;
    }

    public void setBillDiscounts(List<Discount> billDiscounts) {
        checkDiscounts(billDiscounts);
        this.billDiscounts = billDiscounts;
    }
    
    public boolean addDiscount(Discount discount){
        this.billDiscounts.add(discount);
        
        Iterator<Discount> iter = billDiscounts.iterator();
        int exclusiveNum = 0;
        while(iter.hasNext()){
            Discount tmpDis = iter.next();
            
            if(tmpDis.isExclusive() && tmpDis.isActive()){
                exclusiveNum ++;
                if(exclusiveNum > 1){
                    billDiscounts.remove(discount);
                    return false;
                }
            }
        }
        
        return true;
    }
    
    public boolean removeDiscount(Discount discount){
        return this.billDiscounts.remove(discount);
    }
    
    private void checkDiscounts(List<Discount> discounts){
        Iterator<Discount> iter = discounts.iterator();
        int exclusiveNum = 0;
        while(iter.hasNext()){
            Discount tmpDis = iter.next();
            
            if(tmpDis.isExclusive() && tmpDis.isActive()){
                exclusiveNum ++;
                if(exclusiveNum > 1){
                    throw new InvalidDiscountsException();
                }
            }
        }
    }

    public boolean isDiscountEnabled() {
        return discountEnabled;
    }

    public void setDiscountEnabled(boolean discountEnabled) {
        this.discountEnabled = discountEnabled;
    }
    

    public boolean isBillable() {
        return billable;
    }

    public void setBillable(boolean billable) {
        this.billable = billable;
    }

    public boolean isAbsentfree() {
        return absentfree;
    }

    public void setAbsentfree(boolean absentfree) {
        this.absentfree = absentfree;
    }

    public Facility() {
        this.discountEnabled = false;
        this.billable = true;
        this.absentfree = false;
        this.billDiscounts = new ArrayList<>();
    }
    
    
    
    
    public Facility(String name, Property property) {
        this.discountEnabled = false;
        this.billable = true;
        this.absentfree = false;
        this.name = name;
        this.property = property;
        this.billDiscounts = new ArrayList<>();
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Property getProperty() {
        return property;
    }

    public void setProperty(Property property) {
        this.property = property;
    }

   
}
